#include "statistic.h"
#include "muduo/base/ThreadLocal.h"
#include "muduo/base/Logging.h"
#include <fstream>
#include <map>
#include <filesystem>

using namespace muduo;
using std::lock_guard;
namespace fs = std::filesystem;

mutex Statistic::mutex_;
Statistic *Statistic::instance_{nullptr};

Statistic::Statistic()
  : userMap_()
  , local_mutex_() {
}

Statistic::~Statistic() { }

void Statistic::CollectUserData(const std::string &userName, uint64_t bytes) {
  lock_guard<mutex> lock(local_mutex_);
  LOG_DEBUG << "collect " << bytes << " for " << userName;
  auto iter = userMap_.find(userName);
  if (iter == userMap_.end()) {
    userMap_[userName] = bytes;
  } else {
    userMap_[userName] += bytes;
  }
}

void Statistic::SyncStatisticData(const std::string &workDir) {
  lock_guard<mutex> lock(local_mutex_);
  LOG_INFO << "collect user flow data";
  fs::path workPath(workDir);
  workPath.append("flowdata");
  std::fstream file(workPath.u8string(), file.out);
  if (!file.is_open()) {
    LOG_ERROR << "open flowdata file failure";
  }

  file << Timestamp::now().toString() << " ";
  for (auto& [user, data] : userMap_) {
    LOG_INFO << "user: " << user << " used " << data << " bytes data";
    file << user << " " << data << std::endl;
  }

  userMap_.clear();
  LOG_INFO << "clear userMap for size: " << userMap_.size();
}

Statistic *Statistic::getInstance() {
  lock_guard<mutex> mtx(mutex_);
  if (instance_ == nullptr) {
    instance_ = new Statistic();
  }
  return instance_;
}
